package com.xiongjie.ClusterLimit.Interface.impl;

import com.xiongjie.ClusterLimit.Interface.IClusterLimit;
import com.xiongjie.ClusterLimit.entity.ClusterLimitEntity;
import org.infinispan.Cache;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.locks.ReentrantLock;

public abstract class IClusterLimitImpl implements IClusterLimit {

    final private Cache<String, Object> cache;

    public IClusterLimitImpl(Cache<String, Object> cache) {
        this.cache = cache;
    }

    @Override
    final public ClusterLimitEntity getValueByName(String name) {

        boolean limit;

        //1.令牌桶限流操作
        final ReentrantLock lock = (ReentrantLock) cache.get("lock");
        lock.lock();
        try {
            ArrayBlockingQueue<Object> tokenBucket= (ArrayBlockingQueue<Object>) cache.get("tokenBucket");
            if(tokenBucket.size()<=0){
                limit=true;
            }else{
                tokenBucket.poll();
                limit=false;
            }
        } finally {
            lock.unlock();
        }

        //被限流了
        if(limit){
            return null;
        }

        //2.缓存缓存操作
        ClusterLimitEntity entity = (ClusterLimitEntity) cache.get(name);
        if (entity == null) {
            entity = getClusterLimitEntity(name);
            cache.put(name, entity);
        }
        return entity;
    }

    protected abstract ClusterLimitEntity getClusterLimitEntity(String name);
}
